package scau.online.web.user;

import com.alibaba.fastjson.JSON;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.DataBinder;
import org.springframework.web.bind.annotation.*;
import scau.cty.base.common.BaseController;
import scau.cty.base.common.IBaseService;
import scau.cty.dictionary.Code;
import scau.cty.entity.*;
import scau.online.Validator.AddressValidator;
import springfox.documentation.annotations.ApiIgnore;

import javax.validation.Valid;
import java.util.*;

/**
 * Created by Administrator on 2017/3/27.
 */
@Api(value = "用户管理控制器",description = "个人管理接口(需要登录)")
@RestController
@RequestMapping(value = "/user",produces = "application/json")
public class UserController extends BaseController{

    private static Logger logger = LogManager.getLogger(UserController.class);

    @Autowired
    private IBaseService<Role> roleIBaseService;
    @Autowired
    private IBaseService<User> userIBaseService;
    @Autowired
    private IBaseService<Address> addressIBaseService;
    @Autowired
    private IBaseService<CollectionGoods> collectionIBaseService;
    @Autowired
    private IBaseService<Goods> goodsIBaseService;

    /**
     * 绑定地址对象 格式验证器
     * @param binder
     */
    @InitBinder("Address")
    public void initBinder(DataBinder binder){binder.setValidator(new AddressValidator());}



    /**
     * 为本控制器下的所有方法获取登陆用户的username 和 user_id
     * @return
     */

    @ModelAttribute
    public User getUsername(){
        Subject subject = SecurityUtils.getSubject();
        String username = (String) subject.getPrincipal();
        User user = userIBaseService.findSelectPropertyWhereAnd("username",username,"id","username").get(0);
        return user;
    }

    @ApiIgnore
    @RequiresRoles("superadmin")
    @GetMapping("/test")
    public String testUser(@ModelAttribute String username){
//        Subject subject = SecurityUtils.getSubject();
//        String username = (String)subject.getPrincipal();
        System.out.println("看下是不是哪里都可以拿到这个玩意"+username);
        return JSON.toJSONString("操作成功");
    }

    /**
     * 个人中心  用于显示个人账号 和 角色
     * @return
     */
    @ApiOperation(value = "返回登录的用户信息和角色", httpMethod = "GET", produces = "application/json")
    @ResponseBody
    @GetMapping("/center")
    public String getUserMessage(){
        Map map = new LinkedHashMap();
        Subject subject = SecurityUtils.getSubject();
        String username = (String) subject.getPrincipal();
        User user = userIBaseService.findSelectPropertyWhereAnd("username",username,"username").get(0);
        // 查等级 进而查询角色
        Integer rank = userIBaseService.findSelectPropertyWhereAnd("username",user.getUsername(),"roleRank").get(0).getRoleRank();
        String roleMessage = roleIBaseService.findSelectPropertyWhereAnd("rank",rank,"rankMessage").get(0).getRoleMessage();
        map.put("username",user.getUsername());
        map.put("roleMessage",roleMessage);
        sendCode(map, Code.OPERATION_SUCCESS); //操作成功 返回码1
        return JSON.toJSONString(map);
    }

    /**
     * 个人收货地址列表
     * @return
     */
    @ApiOperation(value = "个人收货地址列表")
    @GetMapping("/address")
    public String getAddressList(){
        Map map = new LinkedHashMap();
        Subject subject = SecurityUtils.getSubject();
        String username = (String) subject.getPrincipal();
        User user = userIBaseService.findSelectPropertyWhereAnd("username",username,"id").get(0);
        List<Address> addressList = addressIBaseService.findSelectPropertyWhereAnd("userId",user.getId());
        map.put("addressList",addressList);
        sendCode(map,Code.OPERATION_SUCCESS); //操作成功 返回码1
        return JSON.toJSONString(map);
    }

    /**
     * 新增地址 若新增地址为默认地址 则需先把原本默认地址取消
     * @param address
     * @param result
     * @return
     */
    @ApiOperation(value = "新增地址,需要验证格式")
    @ApiImplicitParams({@ApiImplicitParam(name = "username",value = "用户账号",required = true,dataType = "String",paramType = "query"),
            @ApiImplicitParam(name = "phone",value = "收货电话",required = true,dataType = "String",paramType = "query"),
            @ApiImplicitParam(name = "name",value = "收货人姓名",required = true,dataType = "String",paramType = "query"),
            @ApiImplicitParam(name = "content",value = "详细地址",required = true,dataType = "String",paramType = "query"),
            @ApiImplicitParam(name = "postcode",value = "邮编号码",required = true,dataType = "String",paramType = "query"),
            @ApiImplicitParam(name = "defaultChoice",value = "是否默认地址，1是，0否",required = true,dataType = "Integer",paramType = "query"),

    })
    @PostMapping("/insert_address")
    public String addNewAddress(@Valid Address address, BindingResult result){
        Map map = new LinkedHashMap();
        Subject subject = SecurityUtils.getSubject();
        String username = (String) subject.getPrincipal();
        User user = userIBaseService.findSelectPropertyWhereAnd("username",username,"id","username").get(0);
        if(result.hasErrors()){
            sendCode(map,Code.ILLEGAL_DATA_ERROR);
            logger.info(user.getUsername()+"新增地址，地址格式有误！");
            return JSON.toJSONString(map);
        }
        address.setUserId(user.getId());
        if(address.getDefaultChoice() == 1){
            List<String> pro = new ArrayList<>();
            List<String> val = new ArrayList<>();
            pro.add("userId");
            pro.add("defaultChoice");
            val.add(user.getId());
            val.add("1");
            //查出原本为默认的地址
            List<Address> addressList = addressIBaseService.findSelectPropertyWhereAnd(pro,val);
            if(addressList.size()!=0){
                Address address1 = addressList.get(0);
                address1.setDefaultChoice(0); //设置为非默认
                addressIBaseService.updateNotNull(address1);
            }
        }
        //新增新地址
        addressIBaseService.add(address);
        sendCode(map,Code.OPERATION_SUCCESS);
        return JSON.toJSONString(map);
    }

    /**
     * 修改个人地址接口
     * @param address
     * @return
     */
    @ApiOperation(value = "新增地址,需要验证格式（主要是不能为空）")
    @ApiImplicitParams({@ApiImplicitParam(name = "id",value = "要修改地址的唯一id",required = true,dataType = "String",paramType = "query"),
            @ApiImplicitParam(name = "phone",value = "收货电话",required = true,dataType = "String",paramType = "query"),
            @ApiImplicitParam(name = "name",value = "收货人姓名",required = true,dataType = "String",paramType = "query"),
            @ApiImplicitParam(name = "content",value = "详细地址",required = true,dataType = "String",paramType = "query"),
            @ApiImplicitParam(name = "postcode",value = "邮编号码",required = true,dataType = "String",paramType = "query"),
            @ApiImplicitParam(name = "defaultChoice",value = "是否默认地址，1是，0否",required = true,dataType = "Integer",paramType = "query"),

    })
    @PostMapping("/update_address")
    public String modifyAddress(Address address){
        Map map = new LinkedHashMap();
        if(address.getId() == null ||address.getId() == ""){
            sendCode(map,Code.ILLEGAL_DATA_ERROR);
            return JSON.toJSONString(map);
        }
        Subject subject = SecurityUtils.getSubject();
        String username = (String) subject.getPrincipal();
        User user = userIBaseService.findSelectPropertyWhereAnd("username",username,"id","username").get(0);
        if(address.getDefaultChoice() == 1){
            List<String> pro = new ArrayList<>();
            List<String> val = new ArrayList<>();
            pro.add("userId");
            pro.add("defaultChoice");
            val.add(user.getId());
            val.add("1");
            //查出原本为默认的地址
            List<Address> addressList = addressIBaseService.findSelectPropertyWhereAnd(pro,val);
            if(addressList.size()!=0){
                Address address1 = addressList.get(0);
                address1.setDefaultChoice(0); //设置为非默认
                addressIBaseService.updateNotNull(address1);
            }
        }
        addressIBaseService.updateNotNull(address);
        sendCode(map,Code.OPERATION_SUCCESS);
        return JSON.toJSONString(map);
    }

    /**
     * 设置指定地址为用户的默认地址
     * @param id
     * @return
     */
    @ApiOperation(value = "设置指定地址为用户的默认地址")
    @PostMapping("/set_default")
    @ApiImplicitParam(name = "id",value = "地址的唯一标识",required = true,dataType = "String",paramType = "query")
    public String setDefaultAddress(String id){
        Map map = new LinkedHashMap();
        Subject subject = SecurityUtils.getSubject();
        String username = (String) subject.getPrincipal();
        String userId = userIBaseService.findSelectPropertyWhereAnd("username",username,"userId").get(0).getId();
        List<String> proList = new ArrayList<>();
        List valueList = new ArrayList<>();
        proList.add("userId");
        proList.add("defaultChoice");
        valueList.add(userId);
        valueList.add(1);
        List<Address> addresses = addressIBaseService.findSelectPropertyWhereAnd(proList,valueList);
        if(addresses.size()!= 0){
            Address address = addresses.get(0);
            address.setDefaultChoice(0);
            addressIBaseService.updateNotNull(address); //讲原本默认地址设置为非默认
        }
        //设置请求地址 为默认
        List<Address> addressList = addressIBaseService.findSelectPropertyWhereAnd("id",id);
        if(addressList.size()!= 0){
            Address address1  = addressList.get(0);
            address1.setDefaultChoice(1);
            addressIBaseService.updateNotNull(address1);
        }
        sendCode(map,Code.OPERATION_SUCCESS);
        return JSON.toJSONString(map);
    }



    /**
     * 获取用户登录的默认收货地址
     *
     * @return
     */
    @ApiOperation(value = "获取用户的默认收货地址")
    @GetMapping("/default_address")
    public String getUserDefaultAddress(){
        Map map = new LinkedHashMap();
        Subject subject = SecurityUtils.getSubject();
        String username = (String) subject.getPrincipal();
        String userId = userIBaseService.findSelectPropertyWhereAnd("username",username,"userId").get(0).getId();
        List<String> proList = new ArrayList<>();
        List valueList = new ArrayList<>();
        proList.add("userId");
        proList.add("defaultChoice");
        valueList.add(userId);
        valueList.add(1);
        List<Address> addressList = addressIBaseService.findSelectPropertyWhereAnd(proList,valueList);
        if(addressList.size() != 0){
            map.put("address",addressList.get(0));
        }
        sendCode(map,Code.OPERATION_SUCCESS);
        return JSON.toJSONString(map);
    }




    /**
     * 判断登陆用户是否已收藏指定商品  一般用于查看商品详情的时候访问
     * @param goodsId
     * @return
     */
    @ApiOperation(value = "判断登陆用户是否已收藏改商品")
    @ApiImplicitParam(name = "goodsId",value = "要判断的商品id",required = true,dataType = "String",paramType = "query")
    @GetMapping("check_collection")
    public String checkCollectionWhether(String goodsId){
        Map map = new LinkedHashMap();
        if(goodsId == null || goodsId == ""){
            sendCode(map,Code.ILLEGAL_DATA_ERROR);
            return JSON.toJSONString(map);
        }
        Subject subject = SecurityUtils.getSubject();
        String username = (String) subject.getPrincipal();
        User user = userIBaseService.findSelectPropertyWhereAnd("username",username,"id").get(0);
        List<String> proList = new ArrayList<>();
        List<String> valueList = new ArrayList<>();
        proList.add("userId");
        proList.add("goodsId");
        valueList.add(user.getId());
        valueList.add(goodsId);
        List<CollectionGoods> collectionGoodsList = collectionIBaseService.findSelectPropertyWhereAnd(proList,valueList,"id");
        if(collectionGoodsList.size() == 0){
            sendCode(map,Code.UN_COLLECTED);
            return JSON.toJSONString(map);
        }else{
            sendCode(map,Code.ALREADY_COLLECTED);
            return JSON.toJSONString(map);
        }
    }


    /**
     * 增加商品到我收藏
     * @param goodsId
     * @return
     */
    @ApiOperation(value = "登录用户添加收藏商品")
    @ApiImplicitParam(name = "goodsId",value = "要加入收藏的商品id",required = true,dataType = "String",paramType = "query")
    @PostMapping("/add_collection")
    public String addNewCollection(String goodsId){
        Map map = new LinkedHashMap();
        if(goodsId == null || goodsId == ""){
            sendCode(map,Code.ILLEGAL_DATA_ERROR);
            return JSON.toJSONString(map);
        }
        Subject subject = SecurityUtils.getSubject();
        String username = (String) subject.getPrincipal();
        User user = userIBaseService.findSelectPropertyWhereAnd("username",username,"id").get(0);
        //判断该商品是否已在收藏列表当中
        List<String> proList = new ArrayList<>();
        List<String> valueList = new ArrayList<>();
        proList.add("userId");
        proList.add("goodsId");
        valueList.add(user.getId());
        valueList.add(goodsId);
        if(collectionIBaseService.findSelectPropertyWhereAnd(proList,valueList,"id").size() != 0){
            sendCode(map,Code.ALREADY_COLLECTED);
            return JSON.toJSONString(map);
        }
        List<Goods> goodsList = goodsIBaseService.findSelectPropertyWhereAnd("id",goodsId,"title","thumbnail","price");
        if(goodsList.size() != 0){ //设置值给待插入的collectionGoods对象
            CollectionGoods collectionGoods = new CollectionGoods();
            collectionGoods.setUserId(user.getId());
            collectionGoods.setGoodsId(goodsId);
            collectionGoods.setTitle(goodsList.get(0).getTitle());
            collectionGoods.setThumbnail(goodsList.get(0).getThumbnail());
            collectionGoods.setPrice(goodsList.get(0).getPrice());
            collectionIBaseService.add(collectionGoods);
        }
        sendCode(map,Code.OPERATION_SUCCESS);
        return JSON.toJSONString(map);
    }


    /**
     * 登陆用户后的个人收藏列表
     * 返回几个关键字段 直接显示商品信息 不需另外关联查询
     *
     * @return
     */
    @ApiOperation(value = "获取登陆用户的收藏列表")
    @GetMapping("/collections")
    public String getUserCollectionList(){
        Map map = new LinkedHashMap();
        Subject subject = SecurityUtils.getSubject();
        String username = (String) subject.getPrincipal();
        User user = userIBaseService.findSelectPropertyWhereAnd("username",username,"id").get(0);
        List<CollectionGoods> collectionGoodsList = collectionIBaseService.findSelectPropertyWhereAnd("userId",user.getId());
        map.put("collectionGoodsList",collectionGoodsList);
        sendCode(map,Code.OPERATION_SUCCESS);
        return JSON.toJSONString(map);

    }

    /**
     * 根据收藏的唯一标识删除 无需登录用户的信息
     * 要求前端传入收藏商品的唯一标识
     * @param collectionGoodsId
     * @return
     */
    @ApiOperation(value = "登陆用户删除已收藏商品")
    @ApiImplicitParam(name = "collectionGoodsId",value = "要删除的收藏商品唯一id(非goodsId)",required = true,dataType = "String",paramType = "query")
    @PostMapping("/remove_collection")
    public String deleteUserCollection(String collectionGoodsId){
        Map map = new LinkedHashMap();
        if(collectionGoodsId == null || collectionGoodsId == ""){
            sendCode(map,Code.ILLEGAL_DATA_ERROR);
            return JSON.toJSONString(map);
        }
        collectionIBaseService.delete(collectionGoodsId);
        sendCode(map,Code.OPERATION_SUCCESS);
        return JSON.toJSONString(map);
    }


    /**
     * 批量删除我的收藏
     *
     */
    @ApiOperation(value = "批量删除用户的我的收藏")
    @ApiImplicitParam(name = "idArr" ,value = "要删除的收藏商品的唯一id 的数组(非goodsId)",required = true,dataType = "array",
    paramType = "query")
    @PostMapping("/remove_batch_collections")
    public String removeCollection(String [] idArr){
        Map map = new LinkedHashMap();
        if(idArr == null || idArr.length == 0){
            sendCode(map,Code.ILLEGAL_DATA_ERROR);
            return JSON.toJSONString(map);
        }
        collectionIBaseService.deleteByIds(idArr);
        sendCode(map,Code.OPERATION_SUCCESS);
        return JSON.toJSONString(map);

    }







}
